package model.displayer;

import controller.MainController;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Shape;
import model.Point;

import java.util.Iterator;

public abstract class ShapeDisplayerJFxImpl implements ShapeDisplayer
{
    public static final Color DEFAULT_STROKE = Color.BLACK;
    public static final Color DEFAULT_FILL = Color.TRANSPARENT;
    public static final int DEFAULT_STROKE_WIDTH = 3;
    public static final int OUTSTANDING_STROKE_WIDTH = 6;

    protected ShapeDisplayer father;
    protected MainController controller;
    protected Shape shape;
    protected Pane canvas;

    protected ShapeDisplayerJFxImpl(Pane canvas,MainController controller)
    {
        this.canvas = canvas;
        this.controller = controller;
        this.father = null;
    }

    public void show()
    {
        if(!canvas.getChildren().contains(this.shape))
            canvas.getChildren().add(this.shape);
    }

    public void setColor(Color color)
    {
        this.shape.setStroke(color);
    }

    public Color getColor(){return (Color)this.shape.getStroke();}

    public void setSelected(boolean isSelected)
    {
        if(isSelected)
            shape.getStrokeDashArray().addAll(10.0,10.0,10.0,10.0);
        else
            shape.getStrokeDashArray().clear();
    }

    public void setOutStanding(boolean isOutStanding)
    {
        if(isOutStanding)
            shape.setStrokeWidth(OUTSTANDING_STROKE_WIDTH);
        else
            shape.setStrokeWidth(DEFAULT_STROKE_WIDTH);
    }

    public void clear()
    {
        if(canvas.getChildren().contains(shape))
            canvas.getChildren().remove(shape);
    }

    public void expand(double multi)
    {
        if(multi < 0) return ;
        this.resize(multi);
    }

    public void shrink(double multi)
    {
        if(multi >= 1 || multi < 0) return ;
        this.resize(-multi);
    }

    public void move(double x,double y)
    {
        Point center = getCenter();
        Point newCenter = new Point(center.getX() + x,center.getY() + y);
        setCenter(newCenter);
    }

    // Leaf Node
    public void addChild(ShapeDisplayer child){}

    //Leaf Node
    public void removeChild(ShapeDisplayer child){}

    //Leaf Node
    @Override
    public Iterator<ShapeDisplayer> iterator(){return null;}

    //Leaf Node
    public void setFather(ShapeDisplayer father){this.father = father;}

    public ShapeDisplayer getFather(){return this.father;}

    public abstract ShapeDisplayer clone();

    public abstract void setLocation(Point start,Point end);

    protected abstract void resize(double multi);

    protected abstract Point getCenter();

    protected abstract void setCenter(Point center);

}